#ifndef TRACKBALLINTERACTOR_H
#define TRACKBALLINTERACTOR_H

#include "camera.h"

#define GLM_FORCE_RADIANS
#include <glm/gtc/quaternion.hpp>

namespace llx {

class TrackBallInteractor
{
public:
    typedef enum CameraMotionType{
        NONE,ARC,FIRSTPERSON,PAN,ROLL,ZOOM
    }CameraMotionType;

    static const glm::vec3 X,Y,Z;

    TrackBallInteractor();
    ~TrackBallInteractor();

    void computePointOnSphere(const glm::vec2 &point,glm::vec3 &result);
    void computeRotationBetweenVectors(const glm::vec3 &u,const glm::vec3 &v,glm::quat &result);

    Camera* getCamera();
    CameraMotionType getMotionLeftClick();
    CameraMotionType getMotionMiddleClick();
    CameraMotionType getMotionRightClick();
    CameraMotionType getMotionScroll();
    void setCamera(Camera *c);

    void setScrollDirection(bool up);
    void setClickPoint(double x,double y);
    void setLeftClicked(bool value);
    void setMiddleClicked(bool value);
    void setMotionLeftClick(CameraMotionType motion);
    void setMotionMiddleClick(CameraMotionType motion);
    void setMotionRightClick(CameraMotionType motion);
    void setMotionScroll(CameraMotionType motion);
    void setRightClicked(bool value);
    void setScreenSize(float width,float height);
    void setSpeed(float s);
    void tupdate();

protected:
    char clickQuadrant(float x,float y);
    void computeCameraEye(glm::vec3 &eye);
    void computeCameraUp(glm::vec3 &up);
    void computePan(glm::vec3 &pan);
    void drag();
    void drag(bool isClicked,CameraMotionType motion);
    void dragArc();
    // Change eye position and up direction while keeping center point static.
    void dragArcCamera(){}
    void dragFirstPerson();
    void dragZoom();
    // Simulate zoom by moving camera along viewing eye direction.
    void dragZoomCamera(){}
    // Move camera focal center position with static up and eye direction.
    void dragPan();
    // Roll about eye direction.
    void rollCamera();
    void freezeTransform();
    void scroll();
    void updateCameraEyeUp(bool eye, bool up);

private:
    Camera *mCamera;
    CameraMotionType mCameraMotionLeftClick = ARC;
    CameraMotionType mCameraMotionMiddleClick = ROLL;
    CameraMotionType mCameraMotionRightClick = FIRSTPERSON;
    CameraMotionType mCameraMotionScroll = ZOOM;
    glm::vec2 mClickPoint;
    float mHeight = 1.0f;
    bool mIsDragging = false;
    bool mIsLeftClick = false;
    bool mIsMiddleClick = false;
    bool mIsRightClick = false;
    bool mIsScrolling = false;
    float mPanScale = 0.005f;
    glm::vec2 mPrevClickPoint;
    float mRollScale = 0.005f;
    float mRollSum = 0.0f;
    glm::quat mRotation = glm::quat(1.0f,0.0f,0.0f,0.0f);
    glm::quat mRotationSum = glm::quat(1.0f,0.0f,0.0f,0.0f);
    float mSpeed = 1.0f;
    glm::vec3 mStartVector;
    glm::vec3 mStopVector;
    float mTranslateLength;
    float mWidth = 1.0f;
    float mZoomSum = 0.0f;
    float mZoomScale = 0.1f;
};

} //end namespace llx



#endif // TRACKBALLINTERACTOR_H
